/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "面.h"

#include "core/几何计算/相交.h"

#include "底层绘图/intern/Vulkan/Vulkan框架.h"
#include "底层绘图/intern/绘图框架.h"
#include "intern/网格变换/顶点矩阵变换.h"
#include "intern/管线/3D预设材质.h"
#include "intern/矢量绘图着色材质.h"
#include "intern/网格.h"


#include <file_载入保存数据.h>
#include <几何图形/图形相交.h>
#include <三角形.h>
#include <core/引擎配置.h>
#include <matXX.h>





void f_surface_初始化网格GPU内存(S_设备环境& ctx) {
	uint32 Flags;
	if (ctx.m_支持光追) {
		Flags = E_板载缓存类型::e_TBOs | E_板载缓存类型::e_TBOd;

		//f_buf_getGlobal().g_TLAS_0 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_光追顶层加速结构, E_板载缓存类型::e_光追顶层加速结构 | Flags, 1, 256);
		//f_buf_getGlobal().g_TLAS_1 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_光追顶层加速结构, E_板载缓存类型::e_光追顶层加速结构 | Flags, 1, 256);
		//f_buf_getGlobal().g_BLAS_0 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_光追底层加速结构, E_板载缓存类型::e_光追底层加速结构 | Flags, 1, 1);
		//f_buf_getGlobal().g_BLAS_1 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_光追底层加速结构, E_板载缓存类型::e_光追底层加速结构 | Flags, 1, 1);
		//f_buf_getGlobal().g_实例AS_0 = f_buf_create板载缓存(ctx, sizeof(VkAccelerationStructureInstanceKHR), E_板载缓存类型::e_光追实例, 1);
		//f_buf_getGlobal().g_实例AS_1 = f_buf_create板载缓存(ctx, sizeof(VkAccelerationStructureInstanceKHR), E_板载缓存类型::e_光追实例, 1);

		Flags |= E_板载缓存类型::e_着色端内存地址;

	}
	else {
		f_buf_getGlobal().g_BLAS_0 = nullptr;
		f_buf_getGlobal().g_BLAS_1 = nullptr;
		f_buf_getGlobal().g_TLAS_0 = nullptr;
		f_buf_getGlobal().g_TLAS_1 = nullptr;
		f_buf_getGlobal().g_实例AS_0 = nullptr;
		f_buf_getGlobal().g_实例AS_1 = nullptr;
		//Flags = E_板载缓存类型::e_SSBO | E_板载缓存类型::e_着色端内存地址;
		Flags = E_板载缓存类型::e_着色端内存地址;
	}

	
	f_buf_getGlobal().g_顶点Aabb = f_buf_create板载缓存(ctx, E_板载缓存类型::e_VBO, E_板载缓存类型::e_VBO | E_板载缓存类型::e_光追BVH | Flags, sizeof(S_Aabb), 1);
	f_buf_getGlobal().g_顶点curve = f_buf_create板载缓存(ctx, E_板载缓存类型::e_VBO, E_板载缓存类型::e_VBO | Flags, sizeof(S_CurvePoint3D), 1);
	

	f_buf_getGlobal().g_颜色 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(uint32), 1);
	
	f_buf_getGlobal().g_UV坐标 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(vec2), 1);
	f_buf_getGlobal().g_UV索引 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(uvec3), 1);
	f_buf_getGlobal().g_面 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(S_FaceElement), 0);
	f_buf_getGlobal().g_网格面属性 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(S_MeFaceElement), 0);

	f_buf_getGlobal().g_邻接面索引 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(uvec3), 0);
	f_buf_getGlobal().g_面法线 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(vec3), 0);
	f_buf_getGlobal().g_面中心 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(vec3), 0);

	f_buf_getGlobal().g_网格变换属性 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(S_MeshTranformProp), 1);

	f_buf_getGlobal().g_RtMesh = f_buf_create板载缓存(ctx, sizeof(S_ObMesh), E_板载缓存类型::e_SSBO, 0);
	
	f_buf_getGlobal().g_骨骼属性 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(S_VertBone), 1);
	f_buf_getGlobal().g_骨骼权重 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(S_BoneMap), 1);
	
	f_buf_getGlobal().g_间接 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_INDIRECT, E_板载缓存类型::e_INDIRECT | Flags, sizeof(S_VkDrawIndirectCommand), 1);
	f_buf_getGlobal().g_索引间接 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_INDIRECT, E_板载缓存类型::e_INDIRECT | Flags, sizeof(S_VkDrawIndexedIndirectCommand), 1);

	

	f_buf_getGlobal().g_I32动态属性_点 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(int32), 1);
	f_buf_getGlobal().g_UI32动态属性_点 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(uint32), 1);
	f_buf_getGlobal().g_F32动态属性_点 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(float32), 1);
	f_buf_getGlobal().g_Vec2动态属性_点 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(vec2), 1);
	f_buf_getGlobal().g_Vec3动态属性_点 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(vec3), 1);
	f_buf_getGlobal().g_Vec4动态属性_点 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(vec4), 1);
	f_buf_getGlobal().g_iVec2动态属性_点 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(ivec2), 1);
	f_buf_getGlobal().g_iVec3动态属性_点 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(ivec3), 1);
	f_buf_getGlobal().g_iVec4动态属性_点 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(ivec4), 1);

	f_buf_getGlobal().g_I32动态属性_面 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(int32), 1);
	f_buf_getGlobal().g_UI32动态属性_面 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(uint32), 1);
	f_buf_getGlobal().g_F32动态属性_面 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(float32), 1);
	f_buf_getGlobal().g_Vec2动态属性_面 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(vec2), 1);
	f_buf_getGlobal().g_Vec3动态属性_面 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(vec3), 1);
	f_buf_getGlobal().g_Vec4动态属性_面 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(vec4), 1);
	f_buf_getGlobal().g_iVec2动态属性_面 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(ivec2), 1);
	f_buf_getGlobal().g_iVec3动态属性_面 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(ivec3), 1);
	f_buf_getGlobal().g_iVec4动态属性_面 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(ivec4), 1);

	f_buf_getGlobal().g_文字纹理坐标 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(vec3), 1);
	f_buf_getGlobal().g_字符纹理坐标ID = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(uint32), 1);
	f_buf_getGlobal().g_GPU内存_点_uvec2 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(uvec2), 1);
	f_buf_getGlobal().g_GPU内存_点_uvec3 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(uvec3), 1);


	
	float32 t = 1;
	f_buf_fill(f_buf_getGlobal().g_F32动态属性_点, &t, 1);
	f_buf_fill(f_buf_getGlobal().g_F32动态属性_面, &t, 1);
	vec4 v{1,1,1,1};
	f_buf_fill(f_buf_getGlobal().g_Vec2动态属性_面, &t, 1);
	f_buf_fill(f_buf_getGlobal().g_Vec3动态属性_面, &t, 1);
	f_buf_fill(f_buf_getGlobal().g_Vec4动态属性_面, &t, 1);
	f_buf_fill(f_buf_getGlobal().g_iVec2动态属性_面, &t, 1);
	f_buf_fill(f_buf_getGlobal().g_iVec3动态属性_面, &t, 1);
	f_buf_fill(f_buf_getGlobal().g_iVec4动态属性_面, &t, 1);


	S_全局缓存::g_属性索引 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, E_板载缓存类型::e_SSBO | Flags, sizeof(S_CustomAttr), 1);
	S_CustomAttr ca{};
	f_buf_fill(S_全局缓存::g_属性索引, &ca, 1);


	return;


	{
		//f_buf_getGlobal().m_方形区域光物体网格 = f_surface_创建网格对象(0, ctx, ctx.m_支持光追, E_网格数据枚举::e_Mesh_Vulkan);
		//f_buf_getGlobal().m_圆形区域光物体网格 = f_surface_创建网格对象(0, ctx, ctx.m_支持光追, E_网格数据枚举::e_Mesh_Vulkan);

		std::vector<S_VNT1> 顶点;
		std::vector<uint32> 索引;

		顶点.push_back({ {-1,-1,0}, {0,-1,0}, {0,0} });
		顶点.push_back({ {1,-1,0}, {0,-1,0}, {0,0} });
		顶点.push_back({ {1,1,0}, {0,-1,0}, {0,0} });
		顶点.push_back({ {-1,1,0}, {0,-1,0}, {0,0} });
		索引.push_back(0);
		索引.push_back(1);
		索引.push_back(2);
		索引.push_back(2);
		索引.push_back(3);
		索引.push_back(0);

		//f_mesh_fill顶点数据(f_buf_getGlobal().m_方形区域光物体网格, 顶点);
		//f_mesh_fill索引数据(f_buf_getGlobal().m_方形区域光物体网格, 索引);

		uint32 num = 128;
		std::vector<vec2> 圆顶点(num);
		f_graph_计算圆坐标XY({}, 1.0, num, 圆顶点.data());

		顶点.clear();
		索引.clear();
		顶点.push_back({ {0, 0, 0}, {0,-1,0}, {0,1} });
		for (auto& e : 圆顶点) {
			顶点.push_back({ {e.x, 0, e.y}, {0,-1,0}, {0,0} });
		}


		uint32 index = 5;
		for (uint32 i = 0; i < num; ++i) {
			索引.push_back(4);
			索引.push_back(index);
			索引.push_back(++index);
		}
		索引.back() = 5;

		//f_mesh_fill顶点数据(f_buf_getGlobal().m_圆形区域光物体网格, 顶点);
		//f_mesh_fill索引数据(f_buf_getGlobal().m_圆形区域光物体网格, 索引);
	}




	f_buf_getGlobal().g_骨头锥形 = f_surface_创建网格对象(0, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
	f_buf_getGlobal().g_骨节圆形 = f_surface_创建网格对象(0, ctx, false, E_网格数据枚举::e_Mesh_Vulkan);
	vec2 size = { 1.0f, 0.1f };
	DEF_3Fs V;
	DEF_3Fs N;
	DEF_Is I;
	DEF_2Fs uv;

	f_graph_构建骨骼锥体(size, V, N, I);
	std::vector<S_VNT1> data;
	f_surface_数组合并(data, V);
	f_mesh_fill顶点数据(f_buf_getGlobal().g_骨头锥形, data);
	f_me_fill索引(f_buf_getGlobal().g_骨头锥形, I);
	f_mesh_计算包围盒(f_buf_getGlobal().g_骨头锥形);
	f_surface_计算三角形边相邻面索引(f_buf_getGlobal().g_骨头锥形);

	f_graph_构建球体(64, 32, size.y * 0.5, V, N, uv, I);
	f_surface_数组合并(data, V, N);
	f_mesh_fill顶点数据(f_buf_getGlobal().g_骨节圆形, data);
	f_me_fill索引(f_buf_getGlobal().g_骨节圆形, I);
	f_mesh_计算包围盒(f_buf_getGlobal().g_骨节圆形);
	f_surface_计算三角形边相邻面索引(f_buf_getGlobal().g_骨节圆形);

	f_buf_getGlobal().g_骨头锥形->m_线宽 = 3.0;
	f_buf_getGlobal().g_骨头锥形->m_深度控制 = { 0.0001f, 0.0f };
	f_buf_getGlobal().g_骨节圆形->m_线宽 = 3.0;
	f_buf_getGlobal().g_骨节圆形->m_深度控制 = { 0.0001f, 0.0f };



	{
		f_buf_getGlobal().g_粒子球体网格 = f_surface_创建网格对象(nullptr, ctx, ctx.m_支持光追, E_网格数据枚举::e_Mesh_Vulkan);

		std::vector<S_VNT1> vnData;
		DEF_3Fs 顶点;
		DEF_3Fs 法线;
		DEF_2Fs UV;
		DEF_Is 索引;
		f_graph_构建球体(32, 16, 0.5, 顶点, 法线, UV, 索引);

		f_surface_数组合并(vnData, 顶点, 法线, UV);
		f_mesh_fill顶点数据(f_buf_getGlobal().g_粒子球体网格, vnData);
		f_me_fill索引(f_buf_getGlobal().g_粒子球体网格, 索引);
		f_surface_计算三角形边相邻面索引(f_buf_getGlobal().g_粒子球体网格);
	}
	
	{
		f_buf_getGlobal().g_粒子方体网格 = f_surface_创建网格对象(nullptr, ctx, ctx.m_支持光追, E_网格数据枚举::e_Mesh_Vulkan);

		DEF_3Fs 顶点;
		DEF_3Fs 法线;
		DEF_2Fs UV;
		DEF_Is 索引;
		f_graph_构建立方体({ 1,1,1 }, { 1,1,1 }, 顶点, 法线, UV, 索引);

		std::vector<S_VNT1> vnData;
		f_surface_数组合并(vnData, 顶点, 法线, UV);
		f_mesh_fill顶点数据(f_buf_getGlobal().g_粒子方体网格, vnData);
		f_填充索引数据(f_buf_getGlobal().g_粒子方体网格, 索引);
		f_surface_计算三角形边相邻面索引(f_buf_getGlobal().g_粒子方体网格);
	}
	
	
	{
		std::cout << "init global buffer" << std::endl;
		//S_2D画布::m_间接绘制图元顶点 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_VBO, E_板载缓存类型::e_VBO|E_板载缓存类型::e_SSBO , sizeof(mat3X2), 1);
		//S_2D画布::g变换GPU缓存       = f_buf_create板载缓存(ctx, sizeof(mat3X2), E_板载缓存类型::e_SSBO, 1);
		S_2D画布::g字符GPU缓存       = f_buf_create板载缓存(ctx, sizeof(int32), E_板载缓存类型::e_SSBO, 1);
		//S_2D画布::g行文本变换GPU缓存 = f_buf_create板载缓存(ctx, sizeof(mat3X2), E_板载缓存类型::e_SSBO, 1);
		//S_2D画布::g行文本颜色GPU缓存 = f_buf_create板载缓存(ctx, sizeof(uint32), E_板载缓存类型::e_SSBO, 1);
		S_2D画布::g表格变换GPU缓存     = f_buf_create板载缓存(ctx, sizeof(vec2), E_板载缓存类型::e_SSBO, 1);
		S_2D画布::g表格颜色GPU缓存       = f_buf_create板载缓存(ctx, sizeof(uint32), E_板载缓存类型::e_SSBO, 1);
		S_2D画布::g凸包变换 = f_buf_create板载缓存(ctx, sizeof(mat3X2), E_板载缓存类型::e_SSBO, 1);
		S_2D画布::g凸包颜色 = f_buf_create板载缓存(ctx, sizeof(uint32), E_板载缓存类型::e_SSBO, 1);
		S_2D画布::g凸包线属性 = f_buf_create板载缓存(ctx, sizeof(S_LineProp), E_板载缓存类型::e_SSBO, 1);
		S_2D画布::g凸包渐变属性 = f_buf_create板载缓存(ctx, sizeof(S_ColorGradient), E_板载缓存类型::e_SSBO, 1);
		S_2D画布::g凸包渐变控制属性 = f_buf_create板载缓存(ctx, sizeof(vec4), E_板载缓存类型::e_SSBO, 1);
		S_2D画布::g凸包色轮属性 = f_buf_create板载缓存(ctx, sizeof(S_ColorTake), E_板载缓存类型::e_SSBO);
		S_2D画布::g图标变换 = f_buf_create板载缓存(ctx, sizeof(mat3X2), E_板载缓存类型::e_SSBO);
		S_2D画布::g图标颜色 = f_buf_create板载缓存(ctx, sizeof(uint32), E_板载缓存类型::e_SSBO);
		S_2D画布::g纹理变换 = f_buf_create板载缓存(ctx, sizeof(mat3X2), E_板载缓存类型::e_SSBO);
		S_2D画布::g线段     = f_buf_create板载缓存(ctx, sizeof(S_CurvePoint2), E_板载缓存类型::e_SSBO, 1);
		//f_buf_fill板载缓存(S_2D画布::m_间接绘制图元顶点, m_预设图元顶点);
	}
}

void f_surface3d_释放GPU内存() {

	{
		//f_buf_release板载缓存(S_2D画布::m_间接绘制图元顶点);
		f_buf_release板载缓存(S_2D画布::g字符GPU缓存);
		//f_buf_release板载缓存(S_2D画布::g行文本变换GPU缓存);
		//f_buf_release板载缓存(S_2D画布::g行文本颜色GPU缓存);
		f_buf_release板载缓存(S_2D画布::g凸包变换);
		f_buf_release板载缓存(S_2D画布::g凸包颜色);
		f_buf_release板载缓存(S_2D画布::g凸包线属性);
		f_buf_release板载缓存(S_2D画布::g凸包渐变控制属性);
		f_buf_release板载缓存(S_2D画布::g凸包色轮属性);
		f_buf_release板载缓存(S_2D画布::g图标变换);
		f_buf_release板载缓存(S_2D画布::g图标颜色);
		f_buf_release板载缓存(S_2D画布::g纹理变换);
		f_buf_release板载缓存(S_2D画布::g线段);
	}

	f_surface_销毁网格(f_buf_getGlobal().g_骨头锥形);
	f_surface_销毁网格(f_buf_getGlobal().g_骨节圆形);
	f_surface_销毁网格(f_buf_getGlobal().m_方形区域光物体网格);


	f_buf_release板载缓存(f_buf_getGlobal().g_顶点Aabb);
	f_buf_release板载缓存(f_buf_getGlobal().g_顶点curve);
	f_buf_release板载缓存(f_buf_getGlobal().g_颜色);
	
	f_buf_release板载缓存(f_buf_getGlobal().g_I32动态属性_点);
	f_buf_release板载缓存(f_buf_getGlobal().g_UI32动态属性_点);
	f_buf_release板载缓存(f_buf_getGlobal().g_F32动态属性_点);
	f_buf_release板载缓存(f_buf_getGlobal().g_Vec2动态属性_点);
	f_buf_release板载缓存(f_buf_getGlobal().g_Vec3动态属性_点);
	f_buf_release板载缓存(f_buf_getGlobal().g_Vec4动态属性_点);
	f_buf_release板载缓存(f_buf_getGlobal().g_iVec2动态属性_点);
	f_buf_release板载缓存(f_buf_getGlobal().g_iVec3动态属性_点);
	f_buf_release板载缓存(f_buf_getGlobal().g_iVec4动态属性_点);

	f_buf_release板载缓存(f_buf_getGlobal().g_I32动态属性_面);
	f_buf_release板载缓存(f_buf_getGlobal().g_UI32动态属性_面);
	f_buf_release板载缓存(f_buf_getGlobal().g_F32动态属性_面);
	f_buf_release板载缓存(f_buf_getGlobal().g_Vec2动态属性_面);
	f_buf_release板载缓存(f_buf_getGlobal().g_Vec3动态属性_面);
	f_buf_release板载缓存(f_buf_getGlobal().g_Vec4动态属性_面);
	f_buf_release板载缓存(f_buf_getGlobal().g_iVec2动态属性_面);
	f_buf_release板载缓存(f_buf_getGlobal().g_iVec3动态属性_面);
	f_buf_release板载缓存(f_buf_getGlobal().g_iVec4动态属性_面);


	f_buf_release板载缓存(S_全局缓存::g_属性索引);


	f_buf_release板载缓存(f_buf_getGlobal().g_文字纹理坐标);
	f_buf_release板载缓存(f_buf_getGlobal().g_字符纹理坐标ID);
	f_buf_release板载缓存(f_buf_getGlobal().g_GPU内存_点_uvec2);
	f_buf_release板载缓存(f_buf_getGlobal().g_GPU内存_点_uvec3);

}


void f_surface2D_管线创建(S_设备环境& ctx) {
	auto* rc = f_vk_get绘图环境(ctx);
	
	E_MS次数 采样 = E_MS次数::e_MS_1;

	for (uint32 i = 0; i < 3; ++i) {
		ctx.m_绘图环境->m_2D渲染管线->m_管线_线[E_图层混合模式(i)] = f_初始化_线段材质(ctx, E_图层混合模式(i), 采样);

		ctx.m_绘图环境->m_2D渲染管线->m_管线_图像[E_图层混合模式(i)] = f_创建线管_图像线管(ctx, 采样, E_图层混合模式(i));

		ctx.m_绘图环境->m_2D渲染管线->m_管线_文字[E_图层混合模式(i)] = f_创建线管_多边形线管(ctx, E_MS次数::e_MS_2, E_图层混合模式(i));
		ctx.m_绘图环境->m_2D渲染管线->m_管线_多边形[E_图层混合模式(i)] = f_创建线管_多边形线管(ctx, 采样, E_图层混合模式(i));

		ctx.m_绘图环境->m_2D渲染管线->m_管线_纹理图像[E_图层混合模式(i)] = f_初始化_纹理图像材质(ctx, 采样, E_图层混合模式(i));

		ctx.m_绘图环境->m_2D渲染管线->m_管线_凸包图元面[E_图层混合模式(i)] = f_创建线管_凸包图元(ctx, 采样, E_图层混合模式(i), E_填充模式::e_填充面);

		ctx.m_绘图环境->m_2D渲染管线->m_管线_凸包图元线[E_图层混合模式(i)] = f_创建线管_凸包图元(ctx, 采样, E_图层混合模式(i), E_填充模式::e_填充线);

		ctx.m_绘图环境->m_2D渲染管线->m_管线_刻度线[E_图层混合模式(i)] = f_初始化_刻度线材质(ctx, 采样, E_图层混合模式(i));

	}
	


	ctx.m_绘图环境->m_2D渲染管线->m_管线_图像合成 = f_创建线管_UI图像合成(ctx, rc->m_采样数, E_图层混合模式::e_Normal);
	ctx.m_绘图环境->m_2D渲染管线->m_管线_UI合成 = f_创建线管_UI渲染合成(ctx, E_图层混合模式::e_Normal);

	ctx.m_绘图环境->m_2D渲染管线->m_计算管线_图像合成 = f_创建线管_场景图像合成(ctx);

}

void f_surface2D_管线销毁(S_设备环境& ctx) {
	for (uint32 i = 0; i < 3; ++i) {
		f_df_销毁材质着色器(ctx.m_绘图环境->m_2D渲染管线->m_管线_线[i]);
		f_df_销毁材质着色器(ctx.m_绘图环境->m_2D渲染管线->m_管线_多边形[i]);
		f_df_销毁材质着色器(ctx.m_绘图环境->m_2D渲染管线->m_管线_凸包图元面[i]);
		f_df_销毁材质着色器(ctx.m_绘图环境->m_2D渲染管线->m_管线_凸包图元线[i]);
		f_df_销毁材质着色器(ctx.m_绘图环境->m_2D渲染管线->m_管线_刻度线[i]);
		f_df_销毁材质着色器(ctx.m_绘图环境->m_2D渲染管线->m_管线_纹理图像[i]);
	}
}


void f_surface3D_管线创建(S_设备环境& ctx) {
	auto* rc = f_vk_get绘图环境(ctx);

	for (uint32 i = 0; i < 3; ++i) {
		ctx.m_绘图环境->m_3D渲染管线->m_管线_面[E_图层混合模式(i)] = f_mtl_创建3D线管_面(ctx, E_图层混合模式(i));
		ctx.m_绘图环境->m_3D渲染管线->m_管线_线[E_图层混合模式(i)] = f_mtl_创建3D线管_线(ctx, E_图层混合模式(i));
		ctx.m_绘图环境->m_3D渲染管线->m_管线_点[E_图层混合模式(i)] = f_mtl_创建3D线管_点(ctx, E_图层混合模式(i));
		ctx.m_绘图环境->m_3D渲染管线->m_管线_盒[E_图层混合模式(i)] = f_mtl_创建3D线管_盒(ctx, E_图层混合模式(i));
		ctx.m_绘图环境->m_3D渲染管线->m_管线_注视牌面[E_图层混合模式(i)] = f_mtl_创建3D注视牌管线(ctx, E_图层混合模式(i));
		ctx.m_绘图环境->m_3D渲染管线->m_管线_单色光照面[E_图层混合模式(i)] = f_mtl_场景单色光照管线(ctx, rc->m_采样数, E_图层混合模式(i), E_填充模式::e_填充面);
		ctx.m_绘图环境->m_3D渲染管线->m_管线_颜色ID面[E_图层混合模式(i)] = f_mtl_场景单色光照管线(ctx, rc->m_采样数, E_图层混合模式(i), E_填充模式::e_填充面);
		ctx.m_绘图环境->m_3D渲染管线->m_管线_调试面[E_图层混合模式(i)] = f_mtl_场景单色光照管线(ctx, rc->m_采样数, E_图层混合模式(i), E_填充模式::e_填充面);
	}

	ctx.m_绘图环境->m_3D渲染管线->m_管线_网格基面 = f_mtl_创建网格刻度管线(ctx, E_图层混合模式::e_Normal);

}

void f_surface3D_管线销毁(S_设备环境& ctx) {
	for (uint32 i = 0; i < 3; ++i) {
		f_df_销毁材质着色器(ctx.m_绘图环境->m_3D渲染管线->m_管线_线[i]);
		//f_df_销毁材质着色器(ctx.m_绘图环境->m_3D渲染管线->m_管线_网格刻度线[i]);
		f_df_销毁材质着色器(ctx.m_绘图环境->m_3D渲染管线->m_管线_单色光照面[i]);
		f_df_销毁材质着色器(ctx.m_绘图环境->m_3D渲染管线->m_管线_颜色ID面[i]);
		f_df_销毁材质着色器(ctx.m_绘图环境->m_3D渲染管线->m_管线_调试面[i]);
	}

	f_df_销毁材质着色器(ctx.m_绘图环境->m_3D渲染管线->m_管线_网格基面);

}




S_Mesh* f_surface_创建网格对象(S_Mesh* fromesh, S_设备环境& ctx, bool 开启光追, E_网格数据枚举 type) {
	S_Mesh* me = 0;

	switch (type) {
		case e_Mesh_CPU:
			me = new S_Mesh_CPU();
			break;
		case e_Mesh_CUDA: {
			me = new S_Mesh_CUDA();
			if (fromesh) {
				me->f_AddMesh(*fromesh);
			}
			break;
		}
		
		case e_Mesh_Vulkan: {
			S_VKMesh板载缓存* vm = dynamic_cast<S_VKMesh板载缓存*>(fromesh);
			if (vm) {
				me = new S_VKMesh板载缓存(ctx, vm, fromesh->m_关联顶点, fromesh->m_关联索引, fromesh->m_关联UV, fromesh->m_关联颜色, fromesh->m_关联权重);
			}
			else {
				me = new S_VKMesh板载缓存(ctx);
			}
			break;
		}
	default:
		break;
	}

	if (开启光追) {
		f_me_分配光追几何(me);
	}

	return me;
}

S_Mesh* f_surface_创建网格对象(E_网格数据枚举 type) {
	S_Mesh* me = 0;

	switch (type) {
		case e_Mesh_CPU:
			me = new S_Mesh_CPU();
			break;
		case e_Mesh_CUDA: {
			me = new S_Mesh_CUDA();
			break;
		}			
		case e_Mesh_Vulkan: {
			S_VKMesh板载缓存* buf = new S_VKMesh板载缓存();
			me = buf;
			break;
		}		  
		default:
			break;
	}

	return me;
}

S_Mesh* f_surface_创建网格对象(S_设备环境& ctx, E_网格数据枚举 type) {
	S_Mesh* me = 0;

	switch (type) {
		case e_Mesh_CPU:
			me = new S_Mesh_CPU();
			break;
		case e_Mesh_CUDA: {
			me = new S_Mesh_CUDA();
			break;
		}
		case e_Mesh_Vulkan: {
			S_VKMesh板载缓存* buf = new S_VKMesh板载缓存(ctx);
			me = buf;
			break;
		}
		default:
			return f_surface_创建网格对象();
	}

	return me;
}

void f_surface_销毁网格(S_Mesh* mesh) {
	delete mesh;
}

S_Mesh* f_surface_创建实例(S_Mesh* 源, bool 关联颜色) {
	S_VKMesh板载缓存* me = dynamic_cast<S_VKMesh板载缓存*>(源);
	if (me) {
		S_Mesh* mesh = new S_VKMesh板载缓存(me);

		if (关联颜色) {
			mesh->m_颜色 = me->m_颜色;
		}
		else {
			//f_mesh_创建颜色缓存(mesh, me->m_Ctx);
		}

		return mesh;
	}
	return nullptr;
}

S_Mesh* f_surface_创建实例(S_Mesh* 源, bool 关联顶点, bool 关联索引, bool 关联UV, bool 关联颜色, bool 关联权重, bool 关联属性) {
	S_VKMesh板载缓存* me = dynamic_cast<S_VKMesh板载缓存*>(源);

	if (me) {
		S_Mesh* mesh = new S_VKMesh板载缓存(源->m_Ctx, me, 关联顶点, 关联索引, 关联UV, 关联颜色, 关联权重, 关联属性);
		return mesh;
	}
	return nullptr;
}



void f_surface_关联实例(S_Mesh* mesh, const S_Mesh* 源) {
	S_VKMesh板载缓存* me = dynamic_cast<S_VKMesh板载缓存*>(mesh);
	me->f_拷贝实例(源);
}

void f_surface_Copy(S_Mesh* mesh, const S_Mesh* 源) {
	//assert(源->m_绘制属性字节大小);
	//if (!mesh->m_绘制内存属性) {
	//	mesh->m_绘制内存属性 = malloc(源->m_绘制属性字节大小);
	//	memset(mesh->m_绘制内存属性, 0, 源->m_绘制属性字节大小);
	//}
	////memcpy(mesh->m_绘制内存属性, 源->m_绘制内存属性, 源->m_绘制属性字节大小);
	//mesh->m_绘制属性字节大小 = 源->m_绘制属性字节大小;
	//mesh->m_绘制属性绑定阶段 = 源->m_绘制属性绑定阶段;

	
	if (源->m_关联顶点) {
		mesh->m_顶点 = 源->m_顶点;
		mesh->m_顶点配置Flags = 源->m_顶点配置Flags;

		mesh->m_包围盒 = 源->m_包围盒;
		mesh->m_Bound = 源->m_Bound;
	}
	else {
		//f_mesh_顶点类型切换(mesh, 源);
		f_bm_copy(*mesh->m_顶点, *源->m_顶点);
	}
	mesh->m_关联顶点 = 源->m_关联顶点;


	if (源->m_关联索引) {
		mesh->m_索引 = 源->m_索引;
		mesh->m_材质槽ID = 源->m_材质槽ID;
		
		mesh->m_邻接面索引 = 源->m_邻接面索引;
		mesh->m_面法线 = 源->m_面法线;
		mesh->m_面中心 = 源->m_面中心;
		mesh->m_面 = 源->m_面;
		
		mesh->m_底层光追加速结构 = 源->m_底层光追加速结构;
		mesh->m_光追网格ID = 源->m_光追网格ID;
		mesh->m_网格属性 = 源->m_网格属性;
	}
	else {
		f_bm_copy(*mesh->m_索引, *源->m_索引);
		f_core_array_copy((S_Array*)mesh->m_材质槽ID, (S_Array*)源->m_材质槽ID);

		f_bm_copy(*mesh->m_邻接面索引, *源->m_邻接面索引);
		f_bm_copy(*mesh->m_面法线, *源->m_面法线);
		f_bm_copy(*mesh->m_面中心, *源->m_面中心);

	}
	mesh->m_关联索引 = 源->m_关联索引;


	if (源->m_关联权重) {
		mesh->m_顶点骨骼属性 = 源->m_顶点骨骼属性;
		mesh->m_骨骼权重映射 = 源->m_骨骼权重映射;
	}
	else {
		f_bm_copy(*mesh->m_顶点骨骼属性, *源->m_顶点骨骼属性);
		f_bm_copy(*mesh->m_骨骼权重映射, *源->m_骨骼权重映射);
	}
	mesh->m_关联权重 = 源->m_关联权重;


	if (源->m_关联UV) {
		mesh->m_UV = 源->m_UV;
		mesh->m_UV索引 = 源->m_UV索引;
	}
	else {
		f_bm_copy(*mesh->m_UV, *源->m_UV);
		f_bm_copy(*mesh->m_UV索引, *源->m_UV索引);
	}
	mesh->m_关联UV = 源->m_关联UV;
	
	
	f_bm_copy(*mesh->m_面, *源->m_面);
	//f_bm_copy(mesh->m_网格元素变换属性, 源->m_网格元素变换属性);

	
	
	f_mesh_计算包围盒(mesh);
	mesh->m_更新光追加速结构 = true;
}







S_2D画布* f_surface_创建2D画布(const S_2D画布* fromesh, S_设备环境& ctx) {
	switch (ctx.m_Type) {
		case E_绘图API::E_Vulkan:
			{
				S_2D画布* buf = new S_2D画布(ctx);
				return buf;
			}
			break;
		default:
			break;
	}
	return nullptr;
}

void f_surface_释放2D画布(S_2D画布* fromesh) {
	delete fromesh;
}


void f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<vec3>& data, uint32 vertFlags) {
	*mesh->m_顶点配置Flags = vertFlags;
	mesh->f_fill顶点(data.data(), data.size());
}

void f_mesh_fill颜色数据(S_Mesh* mesh, const std::vector<S_RGBA8UI>& col) {
	mesh->f_fill颜色(col);
}

void f_填充索引数据(S_Mesh* mesh, const std::vector<uint32>& data) {
	f_me_fill索引(mesh, data);
}


void f_surface_set材质ID(S_Mesh* mesh, const std::vector<uint32>& data) {
	mesh->m_面->m_Buf->m_分配块内存锁.lock();

	S_FaceElement* fe = f_buf_面元素_ptr(*mesh->m_面);
	for (uint32 i = 0; i < mesh->m_面->m_Mem.m_数量; ++i) {
		fe[i].MaterialID = data[i];
	}

	mesh->m_面->m_Buf->m_分配块内存锁.unlock();
	return;
}

void f_mesh_fill顶点颜色(S_Mesh* me, const S_RGBA8UI& data) {
	uint32 num = me->m_顶点->m_Mem.m_数量;
	uint32 color = f_PackData4X8(data);
	if (*me->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		
		S_VC* vc = f_buf_VC_ptr(*me->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vc[i].color = color;
		}
	}
}

void f_mesh_fill顶点颜色(S_Mesh* me, const std::vector<S_RGBA8UI>& data, uint32 offset) {
	uint32 num = data.size();
	if (*me->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		
		S_VC* vc = f_buf_VC_ptr(*me->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vc[i + offset].color = f_PackData4X8(data[i]);
		}
	}
}

void f_mesh_fill顶点颜色(S_Mesh* me, const S_RGBA8UI& data, uint32 offset, uint32 num) {
	uint32 color = f_PackData4X8(data);
	if (*me->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		
		S_VC* vc = f_buf_VC_ptr(*me->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vc[i + offset].color = color;
		}
	}
}



void f_surface_get网格顶点数据(S_Mesh* me, const S_UI32Array* index, S_Vec3Array* data, int32 成员) {
	if (!me || !index) {
		return;
	}

	uint32 数量限制 = me->m_顶点->m_Mem.m_数量;
	uint32 num = index->count;
	const uint32* 索引 = index->ptr_userData;

	f_core_array_resize((S_Array*)data, num);
	if(!数量限制) return;

	switch (*me->m_顶点配置Flags) {
		case E_顶点组合标志::e_坐标_法线_UV: {
			S_VNT1* VNT = f_buf_VNT_ptr(*me->m_顶点);
			for (uint32 i = 0; i < num; ++i) {
				uint32 当前索引 = 索引[i];
				if (当前索引 >= 数量限制) {
					当前索引 = 数量限制-1;
				}
				switch (成员) {
					case 0: data->ptr_userData[i] = VNT[当前索引].vert;   break;
					case 1: data->ptr_userData[i] = VNT[当前索引].normal; break;
				}
			}
			break;
		}
		case E_顶点组合标志::e_坐标_法线_UV_颜色: {
			break;
		}
		case E_顶点组合标志::e_坐标: {
			break;
		}
		case E_顶点组合标志::e_坐标_UV: {
			break;
		}
		case E_顶点组合标志::e_坐标_权重: {
			break;
		}
		case E_顶点组合标志::e_坐标_法线: {
			S_VN* xyz = f_buf_VN_ptr(*me->m_顶点);
			break;
		}
		case E_顶点组合标志::e_坐标_颜色: {
			break;
		}
	}
	f_core_array_CleanUnusedMemory((S_Array*)data);
}

void f_surface_set网格顶点数据(S_Mesh* me, const S_UI32Array* index, const S_Vec3Array* data, int32 成员) {
	if(!me || !index) {
		return;
	}

	uint32 数量限制 = me->m_顶点->m_Mem.m_数量 - 1;
	//uint32 num = DEF_Min(index->count, data->count);
	uint32 num = index->count;
	const uint32* 索引 = index->ptr_userData;

	bool 坐标多例 = data->count >= num;

	switch (*me->m_顶点配置Flags) {
		case E_顶点组合标志::e_坐标_法线_UV: {
			S_VNT1* VNT = f_buf_VNT_ptr(*me->m_顶点);
			for (uint32 i = 0; i < num; ++i) {
				uint32 当前索引 = 索引[i];
				if (当前索引 > 数量限制) {
					当前索引 = 数量限制;
				}


				switch (成员) {
					case 0: VNT[当前索引].vert = 坐标多例 ? data->ptr_userData[i] : data->ptr_userData[0];   break;
					case 1: VNT[当前索引].normal = 坐标多例 ? data->ptr_userData[i] : data->ptr_userData[0]; break;
				}
			}
			break;
		}
		case E_顶点组合标志::e_坐标_法线_UV_颜色: {
			break;
		}
		case E_顶点组合标志::e_坐标: {
			break;
		}
		case E_顶点组合标志::e_坐标_UV: {
			break;
		}
		case E_顶点组合标志::e_坐标_权重: {
			break;
		}
		case E_顶点组合标志::e_坐标_法线: {
			S_VN* xyz = f_buf_VN_ptr(*me->m_顶点);
			break;
		}
		case E_顶点组合标志::e_坐标_颜色: {
			break;
		}
	}
}



void f_surface_push顶点(S_Mesh* mesh, const std::vector<vec3>& vert) {
	switch (*mesh->m_顶点配置Flags) {
		case E_顶点组合标志::e_坐标_法线: {
			break;
		}
		case E_顶点组合标志::e_坐标_法线_UV: {
			break;
		}
		case E_顶点组合标志::e_坐标_法线_UV_颜色: {
			break;
		}
		case E_顶点组合标志::e_坐标_UV: {
			break;
		}
		case E_顶点组合标志::e_坐标_颜色: {
			std::vector<uint32> color(vert.size(), 0xffffffff);
			break;
		}
		case E_顶点组合标志::e_坐标_权重: {
			break;
		}

		case E_顶点组合标志::e_坐标:
		default: {
			f_buf_push_back(*mesh->m_顶点, vert);
			break;
		}
	}
	
	if (mesh->m_颜色) {
		std::vector<uint32> color(vert.size(), 0xffffffff);
		//f_buf_push_back(mesh->m_颜色, color);
	}
}

void f_surface_push索引(S_Mesh* mesh, const std::vector<uint32>& index) {
	//f_buf_push_back(mesh->m_索引, index);
	f_buf_push_back(*mesh->m_索引, index);
}

void f_surface_fill纹理坐标索引(S_Mesh* mesh, const std::vector<uint32>& index) {
	f_gbuf_fill(*mesh->m_UV索引, index.data(), 0, index.size() / 3);

	uint32 offset = mesh->m_UV索引->m_Mem.m_偏移;
	mesh->m_几何属性.uvIndexOffset012.x = 0;
	mesh->m_几何属性.uvIndexOffset012.y = 0;
	mesh->m_几何属性.uvIndexOffset012.z = 0;

	mesh->m_几何属性.uvLayerAndOffset.x = 1;
	mesh->m_几何属性.uvLayerAndOffset.y = offset;
}

void f_surface_fill纹理坐标索引(S_Mesh* mesh, const std::vector<uvec3> index[8]) {
	f_bm_resize(*mesh->m_UV索引, 0);

	uint32 offset = 0;

	mesh->m_几何属性.uvLayerAndOffset.x = 0;
	for (uint32 i = 0; i < 8; ++i) {
		switch (i) {
			case 0: mesh->m_几何属性.uvIndexOffset012.x = offset; break;
			case 1: mesh->m_几何属性.uvIndexOffset012.y = offset; break;
			case 2: mesh->m_几何属性.uvIndexOffset012.z = offset; break;
			case 3: mesh->m_几何属性.uvIndexOffset345.x = offset; break;
			case 4: mesh->m_几何属性.uvIndexOffset345.y = offset; break;
			case 5: mesh->m_几何属性.uvIndexOffset345.z = offset; break;
			case 6: mesh->m_几何属性.uvIndexOffset678.x = offset; break;
			case 7: mesh->m_几何属性.uvIndexOffset678.y = offset; break;
				//case 0: mesh->m_几何属性.uvIndexOffset0 = offset; break;
				//case 1: mesh->m_几何属性.uvIndexOffset1 = offset; break;
				//case 2: mesh->m_几何属性.uvIndexOffset2 = offset; break;
				//case 3: mesh->m_几何属性.uvIndexOffset3 = offset; break;
				//case 4: mesh->m_几何属性.uvIndexOffset4 = offset; break;
				//case 5: mesh->m_几何属性.uvIndexOffset5 = offset; break;
				//case 6: mesh->m_几何属性.uvIndexOffset6 = offset; break;
				//case 7: mesh->m_几何属性.uvIndexOffset7 = offset; break;
			default:
				break;
		}

		uint32 num = index[i].size();
		if (num) {
			++mesh->m_几何属性.uvLayerAndOffset.x;
			offset += index[i].size();
		}
		f_buf_push_back(*mesh->m_UV索引, index[i]);
	}
	mesh->m_几何属性.uvLayerAndOffset.z = mesh->m_UV索引->m_Mem.m_偏移;
}

void f_mesh_fill面平滑模式(S_Mesh* mesh, const std::vector<bool> 平直) {
	S_VKMesh板载缓存& me = *dynamic_cast<S_VKMesh板载缓存*>(mesh);

	S_FaceElement* fe = f_buf_面元素_ptr(*mesh->m_面);
	for (uint32 i = 0; i < mesh->m_面->m_Mem.m_数量; ++i) {
		fe[i].FacesMooth = 平直[i];
	}
}

void f_mesh_fill面(S_Mesh* me, const std::vector<S_FaceElement>& 面) {
	f_gbuf_fill(*me->m_面, 面.data(), 0, 面.size()); return;
	//if (me->m_面->m_Mem.m_数量 != 面.size()) {
	//	std::cout << "";
	//}
	me->m_面->m_Buf->m_分配块内存锁.lock();
	auto* fe = f_buf_面元素_ptr(*me->m_面);
	for (uint32 i = 0; i < me->m_面->m_Mem.m_数量; ++i) {
		fe[i].FacesMooth = 面[i].FacesMooth;
		fe[i].MaterialID = 面[i].MaterialID;
		fe[i].MaterialSlot = 面[i].MaterialSlot;
		fe[i].ObType = 面[i].ObType;
	}
	me->m_面->m_Buf->m_分配块内存锁.unlock();
}

void f_surface_fill绘制区间(S_Mesh* mesh, const std::vector<S_VkDrawIndirectCommand>& indirect) {
	if (!mesh->m_间接) {
		mesh->m_间接 = (S_GPU内存块*)malloc(sizeof(S_GPU内存块));
		*mesh->m_间接 = f_bm_alloc(f_buf_getGlobal().g_间接, indirect.size());
	}
	f_gbuf_fill(*mesh->m_间接, indirect.data(), 0, indirect.size());
}

void f_surface_fill绘制区间(S_Mesh* mesh, const std::vector<S_VkDrawIndexedIndirectCommand>& indirect) {
	if (!mesh->m_间接) {
		mesh->m_间接 = (S_GPU内存块*)malloc(sizeof(S_GPU内存块));
		*mesh->m_间接 = f_bm_alloc(f_buf_getGlobal().g_索引间接, indirect.size());
	}
	f_gbuf_fill(*mesh->m_间接, indirect.data(), 0, indirect.size());
}

void f_mesh_fill绘制区间(S_Mesh* me, const S_GPU内存块& bm, uint32 firstInstance, uint32 instanceCount) {
	assert(me->m_间接);
	assert(me->m_间接->m_Buf);
	//assert(me->m_间接->m_Buf->m_Offset == bm.m_Buf->m_Offset);
	if (me->m_间接) {
		f_bm_at<S_VkDrawIndirectCommand>(*me->m_间接) = {
			uint32(bm.m_Mem.m_数量),
			instanceCount,
			uint32(bm.m_Mem.m_偏移),
			firstInstance
		};
	}
}

uint32 f_surface_add间接绘制(S_Mesh* mesh, const S_VkDrawIndirectCommand& indirect) {
	if (!mesh->m_间接) {
		mesh->m_间接 = (S_GPU内存块*)malloc(sizeof(S_GPU内存块));
		*mesh->m_间接 = f_bm_alloc(f_buf_getGlobal().g_间接, 0);
	}
	f_buf_push_back<S_VkDrawIndirectCommand>(*mesh->m_间接, { indirect });
	f_buf_push_back<S_MeshTranformProp>(mesh->m_网格元素变换属性, {f_init_MeshTranform()});
	return mesh->m_间接->m_Mem.m_偏移;
}
uint32 f_surface_add间接绘制(S_Mesh* mesh, const S_VkDrawIndexedIndirectCommand& indirect) {
	if (!mesh->m_间接) {
		mesh->m_间接 = (S_GPU内存块*)malloc(sizeof(S_GPU内存块));
		*mesh->m_间接 = f_bm_alloc(f_buf_getGlobal().g_索引间接, 0);
	}
	
	f_buf_push_back<S_VkDrawIndexedIndirectCommand>(*mesh->m_间接, {indirect});
	f_buf_push_back<S_MeshTranformProp>(mesh->m_网格元素变换属性, { f_init_MeshTranform() });
	return mesh->m_间接->m_Mem.m_数量;
}

void f_surface_mov绘制区间(S_Mesh* mesh, uint32 loc) {
	f_buf_erase(*mesh->m_间接, loc);
	f_buf_erase(mesh->m_网格元素变换属性, loc);
}

void f_surface_set间接绘制区间(S_Mesh* mesh, const S_VkDrawIndirectCommand& indirect, uint32 loc) {
	f_buf_Indirect_at(*mesh->m_间接, loc) = indirect;
}



void f_mesh_fill顶点数据(S_Surface2D* mesh, const std::vector<vec2>& data) {
	f_buf_fill板载缓存(mesh->m_顶点.m_Buf, data, E_板载缓存类型::e_VBO);
}

uint32 f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<S_VNT1>& data) {
	f_mesh_切换顶点类型(mesh, E_顶点组合标志::e_坐标_法线_UV, data.size());
	return mesh->f_填充顶点数据(sizeof(S_VNT1), data.size(), (void*)data.data());
}

uint32 f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<S_VN>& data) {
	f_mesh_切换顶点类型(mesh, E_顶点组合标志::e_坐标_法线, data.size());
	return mesh->f_填充顶点数据(sizeof(S_VN), data.size(), (void*)data.data());
}

uint32 f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<S_VC>& data) {
	//*mesh->m_顶点配置Flags = E_顶点组合标志::e_坐标_颜色;
	f_mesh_切换顶点类型(mesh, E_顶点组合标志::e_坐标_颜色, data.size());
	return mesh->f_填充顶点数据(sizeof(S_VC), data.size(), (void*)data.data());
}

uint32 f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<S_Aabb>& data) {
	//*mesh->m_顶点配置Flags = E_顶点组合标志::e_坐标_颜色;
	f_mesh_切换顶点类型(mesh, E_顶点组合标志::e_包围盒, data.size());
	return mesh->f_填充顶点数据(sizeof(S_Aabb), data.size(), (void*)data.data());
}


void f_surface_fill颜色(S_Mesh* mesh, const S_RGBA8UI& color, uint32 实例S, uint32 数量) {
	//if (数量 > mesh->m_颜色->m_Size - 实例S) {
	//	数量 = mesh->m_颜色->m_Size - 实例S;
	//}
	//
	//mesh->m_颜色->f_map();
	//uint32* color_p = (uint32*)(mesh->m_颜色->m_mappedPtr);
	//
	//for (uint32 i = 0; i < 数量; ++i) {
	//	color_p[i + 实例S] = f_PackData4X8(color);
	//}
	//
	//mesh->m_颜色->f_unmap();
}




void f_surface_get顶点坐标(S_Mesh* mesh, std::vector<vec3>& data) {
	uint32 num = mesh->m_顶点->m_Mem.m_数量;
	data.resize(num);

	if(!num) return;

	vec3* verts = data.data();
	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线 || *mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);

		for (uint32 i = 0; i < num; ++i) {
			verts[i] = vn[i].vert;
		}
	}else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		S_VNT1* vnt = f_buf_VNT_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			verts[i] = vnt[i].vert;
		}
	}
	else {
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
		memcpy(verts, v, num * sizeof(vec3));
	}
	//mesh->f_unmap顶点();
}

void f_surface_get顶点法线(S_Mesh* mesh, std::vector<vec3>& data) {
	uint32 num = mesh->m_顶点->m_Mem.m_数量;
	data.resize(num);

	if (!num) return;

	vec3* verts = data.data();

	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			verts[i] = vn[i].normal;
		}
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		S_VNT1* vnt = f_buf_VNT_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			verts[i] = vnt[i].normal;
		}
	}
	else {
		for (uint32 i = 0; i < num; ++i){
			verts[i] = { 0,1,0 };
		}
	}
}

void f_surface_get纹理坐标(S_Mesh* mesh, std::vector<vec2>& data) {
	uint32 num = mesh->m_顶点->m_Mem.m_数量;
	data.resize(num);

	if (!num) return;

	vec2* verts = data.data();

	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		//S_VNT1* vn = (S_VNT1*)顶点.point;
		S_VNT1* vnt = f_buf_VNT_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			verts[i] = vnt[i].UV;
		}
	}
}

void f_surface_get顶点数据(S_Mesh* mesh, std::vector<S_VN>& data) {
	uint32 num = mesh->m_顶点->m_Mem.m_数量;
	data.resize(num);

	if (!num) return;

	S_VN* verts = data.data();

	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
		memcpy(verts, vn, num * sizeof(S_VN));
	}
	else {
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			verts[i].vert = v[i];
			verts[i].normal = { 0,1,0 };
		}
	}
}

void f_surface_get顶点数据(S_Mesh* mesh, std::vector<S_VC>& data) {
	uint32 num = mesh->m_顶点->m_Mem.m_数量;
	data.resize(num);

	if (!num) return;

	S_VC* verts = data.data();

	switch (*mesh->m_顶点配置Flags) {
		case E_顶点组合标志::e_坐标_颜色: {
			S_VC* vn = f_buf_VC_ptr(*mesh->m_顶点);
			memcpy(verts, vn, num * sizeof(S_VC));
			break;
		}
		case E_顶点组合标志::e_坐标_法线_UV: {
			S_VNT1* vn = f_buf_VNT_ptr(*mesh->m_顶点);
			for (uint32 i = 0; i < mesh->m_顶点->m_Mem.m_数量; ++i) {
				verts[i].color = f_PackData4X8({ 255, 255, 255, 255 });
				verts[i].vert = vn[i].vert;
			}
			break;
		}
		case E_顶点组合标志::e_坐标_法线: {
			S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
			for (uint32 i = 0; i < mesh->m_顶点->m_Mem.m_数量; ++i) {
				verts[i].color = f_PackData4X8({ 255, 255, 255, 255 });
				verts[i].vert = vn[i].vert;
			}
			break;
		}
		default: {
			vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
			for (uint32 i = 0; i < num; ++i) {
				verts[i].vert = v[i];
				verts[i].color = f_PackData4X8({ 255, 255, 255, 255 });
			}
			break;
		}
	}
}


void f_surface_get顶点索引(S_Mesh* mesh, std::vector<uvec3>& data) {
	auto p索引 = (uvec3*)f_buf_UI32_ptr(*mesh->m_索引);
	uint32 num = mesh->m_索引->m_Mem.m_数量;

	data.resize(num / 3);
	if (num) {
		uvec3* index = data.data();
		memcpy((uint8*)index, (uint8*)p索引, num * sizeof(uint32));
	}
}

void f_surface_get顶点索引(S_Mesh* mesh, std::vector<uint32>& data) {
	auto p索引 = (uvec3*)f_buf_UI32_ptr(*mesh->m_索引);
	uint32 num = mesh->m_索引->m_Mem.m_数量;

	data.resize(num);
	if (num) {
		uint32* index = data.data();
		memcpy((uint8*)index, (uint8*)p索引, num * sizeof(uint32));
	}
}

vec3 f_surface_get顶点坐标(S_Mesh* mesh, const Mat44f& mat, uint32 id) {
	vec3 v = {};
	
	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
		v = mat * vn[id].vert;
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		S_VC* vc = f_buf_VC_ptr(*mesh->m_顶点);
		v = mat * vc[id].vert;
	}
	else {
		v = mat * f_buf_Vec3_ptr(*mesh->m_顶点)[id];
	}
	return v;
}

vec3 f_surface_get全局偏移顶点坐标(S_Mesh* mesh, const Mat44f& mat, uint32 id) {
	vec3 v = {};
	auto 顶点 = mesh->m_顶点->m_Buf->m_mappedPtr;
	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		S_VN* vn = (S_VN*)顶点;
		v = mat * vn[id].vert;
		
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		S_VC* vc = (S_VC*)顶点;
		v = mat * vc[id].vert;
	}
	else {
		v = mat * ((vec3*)顶点)[id];
	}
	return v;
}

void f_surface_get材质ID(S_Mesh* mesh, std::vector<int32>& data) {
	S_FaceElement* fe = f_buf_面元素_ptr(*mesh->m_面);

	data.resize(mesh->m_面->m_Mem.m_数量);
	for (uint32 i = 0; i < mesh->m_面->m_Mem.m_数量; ++i) {
		data[i] = fe[i].MaterialID;
	}
}

void f_surface_get面平滑(S_Mesh* mesh, std::vector<int32>& data) {
	S_FaceElement* fe = f_buf_面元素_ptr(*mesh->m_面);

	data.resize(mesh->m_面->m_Mem.m_数量);
	for (uint32 i = 0; i < mesh->m_面->m_Mem.m_数量; ++i) {
		data[i] = fe[i].FacesMooth;
	}
}




void f_surface_合并(const std::vector<S_Mesh*>& meshs, S_Mesh& mesh) {
	S_Mesh_CPU* 网格 = dynamic_cast<S_Mesh_CPU*>(&mesh);

	网格->m_positions.clear();
	网格->m_indices.clear();

	if (网格) {
		uint32 offset = 0;

		for (auto& e : meshs) {
			std::vector<vec3> 顶点;
			f_surface_get顶点坐标(e, 顶点);
			std::vector<uvec3> 索引;
			f_surface_get顶点索引(e, 索引);

			
			uint32 num = 索引.size();
			auto* p_索引 = 索引.data();
			for (uint32 i = 0; i < num; ++i) {
				p_索引[i].x += offset;
				p_索引[i].y += offset;
				p_索引[i].z += offset;
			}
			

			网格->m_positions.insert(网格->m_positions.begin(), 顶点.begin(), 顶点.end());

			offset = 网格->m_indices.size();
			网格->m_indices.resize(offset + num * 3);
			memcpy(&(网格->m_indices[offset]), 索引.data(), num * sizeof(uvec3));

			offset = 网格->m_positions.size();
		}
	}
	
}

void f_surface_数组合并(std::vector<S_VN>& data, const DEF_3Fs& v, const DEF_3Fs& n) {
	
	uint32 num = v.size();
	data.resize(num);

	auto* 包 = data.data();
	auto* 顶点 = v.data();
	auto* 法线 = n.data();
	for (uint32 i = 0; i < num; ++i) {
		包[i].vert = 顶点[i];
		包[i].normal = 法线[i];
	}
}

void f_surface_数组合并(std::vector<S_VC>& data, const DEF_3Fs& v, const std::vector<S_RGBA8UI>& color) {
	uint32 num = v.size();
	data.resize(num);

	auto* 包 = data.data();
	auto* 顶点 = v.data();
	auto* 颜色 = color.data();
	for (uint32 i = 0; i < num; ++i) {
		包[i].vert = 顶点[i];
		包[i].color = f_PackData4X8(颜色[i]);
	}
}

void f_surface_数组合并(std::vector<S_VNT1>& data, const DEF_3Fs& v, const DEF_3Fs& n, const DEF_2Fs& t) {
	uint32 num = v.size();
	data.resize(num);

	auto* 包 = data.data();
	auto* 顶点 = v.data();
	auto* normal = n.data();
	auto* uv = t.data();

	for (int64 i = 0; i < num; ++i) {
		包[i].vert = 顶点[i];
		包[i].normal = normal[i];
		包[i].UV = uv[i];
	}
}

void f_surface_数组合并(std::vector<S_VNTC>& data, const DEF_3Fs& v, const DEF_3Fs& n, const DEF_2Fs& t) {
	uint32 num = v.size();
	data.resize(num);

	auto* 包 = data.data();
	auto* 顶点 = v.data();
	auto* normal = n.data();
	auto* uv = t.data();

	float32 color = 0xffffffff;

	for (int64 i = 0; i < num; ++i) {
		包[i].vert = 顶点[i];
		包[i].normal = normal[i];
		包[i].uv_color = { uv[i].x, uv[i].y, color };
	}
}



void f_surface_数组合并(std::vector<S_VNT1>& data, const DEF_3Fs& v, const DEF_3Fs& n) {
	uint32 num = v.size();
	data.resize(num);

	auto* 包 = data.data();
	auto* 顶点 = v.data();
	auto* normal = n.data();
//#pragma omp_set_num_threads(2);
//#pragma omp parallel for
	for (int64 i = 0; i < num; ++i) {
		包[i].vert = 顶点[i];
		包[i].normal = normal[i];
		包[i].UV = {};
	}
}

void f_surface_数组合并(std::vector<S_VNT1>& data, const DEF_3Fs& v, const DEF_2Fs& t) {
	uint32 num = v.size();
	data.resize(num);

	auto* 包 = data.data();
	auto * 顶点 = v.data();
	auto* uv = t.data();
	for (int64 i = 0; i < num; ++i) {
		包[i].vert = 顶点[i];
		包[i].normal = {0,0,0};
		包[i].UV = uv[i];
	}
}

void f_surface_数组合并(std::vector<S_VNT1>& data, const DEF_3Fs& v) {
	uint32 num = v.size();
	data.resize(num);

	auto* 包 = data.data();
	auto* 顶点 = v.data();
	for (int64 i = 0; i < num; ++i) {
		包[i].vert = 顶点[i];
		包[i].normal = { 0,0,0 };
		包[i].UV = {};
	}
}

void f_surface_计算面中心点(S_Mesh* mesh, std::vector<vec3>& 中心点) {
	auto p索引 = (uvec3*)f_buf_UI32_ptr(*mesh->m_索引);

	uint32 num = mesh->m_索引->m_Mem.m_数量 / 3;
	

	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线 || *mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		//S_VN* vn = (S_VN*)顶点.point;
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);

		for (uint32 i = 0; i < num; ++i) {
			uvec3 index = p索引[i];
			auto q = f_三角形中心坐标(vn[index.x].vert, vn[index.y].vert, vn[index.z].vert);
			中心点.push_back(q);
		}
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		//S_VNT1* vn = (S_VNT1*)顶点.point;
		S_VNT1* vnt = f_buf_VNT_ptr(*mesh->m_顶点);

		for (uint32 i = 0; i < num; ++i) {
			uvec3 index = p索引[i];
			auto q = f_三角形中心坐标(vnt[index.x].vert, vnt[index.y].vert, vnt[index.z].vert);
			中心点.push_back(q);
		}
	}
	else {
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			uvec3 index = p索引[i];
			auto q = f_三角形中心坐标(v[index.x], v[index.y], v[index.z]);
			中心点.push_back(q);
		}
	}
}

void f_surface_计算面法线(S_Mesh* mesh, std::vector<vec3>& 法线) {
	auto p索引 = (uvec3*)f_buf_UI32_ptr(*mesh->m_索引);

	uint32 num = mesh->m_索引->m_Mem.m_数量 / 3;
	
	法线.resize(num);
	auto* normal_ptr = 法线.data();

	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线 || *mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		//S_VN* vn = (S_VN*)顶点.point;
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
#pragma omp parallel for
		for (int32 i = 0; i < num; ++i) {
			uvec3 index = p索引[i];
			normal_ptr[i] = f_surface_FaceNormal(vn[index.x].vert, vn[index.y].vert, vn[index.z].vert);
		}
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		//S_VNT1* vn = (S_VNT1*)顶点.point;
		S_VNT1* vnt = f_buf_VNT_ptr(*mesh->m_顶点);
#pragma omp parallel for
		for (int32 i = 0; i < num; ++i) {
			uvec3 index = p索引[i];
			normal_ptr[i] = f_surface_FaceNormal(vnt[index.x].vert, vnt[index.y].vert, vnt[index.z].vert);
		}
	}
	else {
		//vec3* p顶点 = (vec3*)顶点.point;
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
#pragma omp parallel for
		for (int32 i = 0; i < num; ++i) {
			uvec3 index = p索引[i];
			normal_ptr[i] = f_surface_FaceNormal(v[index.x], v[index.y], v[index.z]);
		}
	}
}

void f_surface_变换(S_Mesh* mesh, const S_Tranform& t) {
	C_Mat44 mat = f_从变换构建矩阵(t.position, t.rotation, t.scale);
	uint32 num = mesh->m_顶点->m_Mem.m_数量;
	
	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线 || *mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vn[i].vert *= mat;
		}
	}
	else {
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			v[i] *= mat;
		}
	}
}



#define DEF_surface_计算包围盒(_v, _num) {		\
	for (uint32 i = 0; i < _num; ++i) {			\
		最大 = vec_Max(最大, _v[i].vert);       \
		最小 = vec_Min(最小, _v[i].vert);       \
	}											\
}                                               \


S_Bounding f_mesh_计算包围盒(S_Mesh* mesh, const Mat44f* mat) {
	uint32 num = mesh->m_顶点->m_Mem.m_数量;
	
	if(!num) {
		*mesh->m_Bound = {};
		*mesh->m_包围盒 = {};
		return {};
	}
	vec3 最小 = {1000000000, 1000000000, 1000000000 };
	vec3 最大 = {-1000000000, -1000000000, -1000000000 };


	S_VNTC* v = f_bm_ptr<S_VNTC>(*mesh->m_顶点);
	for (uint32 i = 0; i < num; ++i) {
		vec3 vert = v[i].vert;

		最大 = vec_Max(最大, vert);
		最小 = vec_Min(最小, vert);
	}	
	*mesh->m_Bound = { 最小 , 最大 };
	return *mesh->m_Bound;
}

S_Bounding f_mesh_计算包围盒(S_Mesh* mesh, uint32 vertOffset, uint32 vertNum) {
	auto* 顶点 = mesh->m_顶点->m_Buf->m_mappedPtr;

	vec3 最小 = {};
	vec3 最大 = {};
	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		S_VN* vn = (S_VN*)顶点;
		DEF_surface_计算包围盒(vn, vertNum);
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		S_VC* vn = (S_VC*)顶点;
		DEF_surface_计算包围盒(vn, vertNum);
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		S_VNT1* vn = (S_VNT1*)顶点;
		DEF_surface_计算包围盒(vn, vertNum);
	}
	else {
		vec3* v = (vec3*)顶点;
		for (uint32 i = 0; i < vertNum; ++i) {
			最大 = vec_Max(最大, v[i]);
			最小 = vec_Min(最小, v[i]);
		}
	}

	*mesh->m_Bound = { 最小 , 最大 };
	//mesh->m_包围盒.size = 最大 - 最小;
	//mesh->m_包围盒.pos = mesh->m_包围盒.size * 0.5 + 最小;
	return *mesh->m_Bound;
}

S_Bounding f_surface_计算曲线包围盒(S_Mesh* mesh) {
	uint32 num = mesh->m_顶点->m_Mem.m_数量;

	if (!num) {
		*mesh->m_Bound = {};
		*mesh->m_包围盒 = {};
		return {};
	}

	bool 使用索引 = true;
	uvec2* p索引 = nullptr;
	if (mesh->m_索引->m_Mem.m_数量) {
		num = mesh->m_索引->m_Mem.m_数量 / 2;
		p索引 = (uvec2*)f_buf_UI32_ptr(*mesh->m_索引);
	}
	else {
		使用索引 = false;
		num /= 2;
	}


	vec3 最小 = { 1000000000, 1000000000, 1000000000 };
	vec3 最大 = { -1000000000, -1000000000, -1000000000 };

	auto* point = f_buf_CurvePoint3D_ptr(*mesh->m_顶点);
	for (uint32 i = 0; i < num; ++i) {
		vec3 v1, v2, vR, vL;
		if (使用索引) {
			uvec2 index = p索引[i];
			v1 = point[index.x].value;
			vR = point[index.x].R_point;
			v2 = point[index.y].value;
			vL = point[index.y].L_point;
		}
		else {
			v1 = (point[i * 2].value);
			vR = (point[i * 2].R_point);
			v2 = (point[i * 2 + 1].value);
			vL = (point[i * 2 + 1].L_point);
		}

		for (uint32 k = 0; k <= 32; ++k) {
			vec3 p0 = f_glsl_cal_CubicCurve(v1, vR, v2, vL, 0.03125f * k);

			最大 = vec_Max(最大, p0);
			最小 = vec_Min(最小, p0);
		}
	}

	return { 最小 , 最大 };
}

vec3 f_mesh_计算包围盒大小(S_Mesh* mesh, const Mat44f& mat) {
	S_Bounding cube = f_mesh_计算包围盒(mesh, &mat);

	cube.max = mat * cube.max;
	cube.min = mat * cube.min;

	return vec_sub(cube.max, cube.min);
}



S_面拾取 f_surface_射线面相交(S_Mesh* mesh, const Mat44f mat[2], const vec3& s, const vec3& dir) {
	S_面拾取 拾取信息{ {}, DEF_PickUp_LineMaxDis, -1 };
	uint32 num = mesh->m_索引->m_Mem.m_数量 / 3;
	if (!num || !mesh->m_顶点->m_Mem.m_数量) return 拾取信息;

	S_VNTC* vert = f_bm_ptr<S_VNTC>(*mesh->m_顶点);
	uvec3* index = (uvec3*)f_bm_ptr<uint32>(*mesh->m_索引);

	

	
	int32 相交情况 = 0;
	vec3 相交坐标 = {};

	for (uint32 i = 0; i < num; ++i) {
		uvec3 trangle = index[i];

		auto v1 = mat[0] * vert[trangle.x].vert;
		auto v2 = mat[0] * vert[trangle.y].vert;
		auto v3 = mat[0] * vert[trangle.z].vert;

		//相交情况 = f_graph_IntersectTriangle(v1, v2, v3, s, dir, &相交坐标);
		相交情况 = f_intersect_射线三角形(v1, v2, v3, s, dir, &相交坐标);
		if (相交情况) {
			float32 距离 = vec_len(vec_sub(相交坐标, s));
			if (距离 < 拾取信息.相交宽度) {
				拾取信息.相交宽度 = 距离;
				拾取信息.交点 = 相交坐标;
				拾取信息.面索引 = i;
			}
		}
	}
	return 拾取信息;
}

S_面拾取 f_surface_射线面相交(S_Mesh* mesh, const Mat44f mat[2], const vec3& s, const vec3& dir, const vec3& 相机位置) {
	S_面拾取 拾取信息{ {}, 1e+7, -1 };

	uint32 num = mesh->f_get顶点数量();
	if (!num) return 拾取信息;

	bool 使用索引 = true;
	uvec3* p索引 = nullptr;
	if (!(mesh->m_索引->m_Mem.m_数量)) {
		使用索引 = false;
		num /= 3;
	}
	else {
		num = mesh->m_索引->m_Mem.m_数量 / 3;
		p索引 = (uvec3*)f_buf_UI32_ptr(*mesh->m_索引);
	}

	const auto& 元素变换属性 = f_buf_网格元素变换属性_at(mesh->m_网格元素变换属性, 0);
	auto viewInverseMat = f_mat44_to_33(mat[1]);

	uint32 线程数 = 16;
	//float32 最小距离 = 900000000.0f;
	//vec3 最小相交坐标 = {};
	vec3 相交坐标 = {};

	


	bool 是否相交 = false;
	int32 相交情况 = 0;
	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		//S_VN* vn = (S_VN*)顶点.point;
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vec3 v1, v2, v3;
			if (使用索引) {
				uvec3 index = p索引[i];
				v1 = vn[index.x].vert;
				v2 = vn[index.y].vert;
				v3 = vn[index.z].vert;
			}
			else {
				v1 = (vn[i * 3].vert);
				v2 = (vn[i * 3 + 1].vert);
				v3 = (vn[i * 3 + 2].vert);
			}
			f_lineMeshTranform(v1, {}, 元素变换属性, mat[0], viewInverseMat, 相机位置);
			f_lineMeshTranform(v2, {}, 元素变换属性, mat[0], viewInverseMat, 相机位置);
			f_lineMeshTranform(v3, {}, 元素变换属性, mat[0], viewInverseMat, 相机位置);

			相交情况 = f_graph_IntersectTriangle(v1, v2, v3, s, dir, &相交坐标);
			if (相交情况) {
				float32 距离 = vec_len(vec_sub(相交坐标, 相机位置));
				if (距离 < 拾取信息.相交宽度) {
					拾取信息.相交宽度 = 距离;
					拾取信息.交点 = 相交坐标;
					拾取信息.面索引 = i;
					是否相交 = true;
				}
			}
		}
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线_UV) {
		S_VNT1* vn = f_buf_VNT_ptr(*mesh->m_顶点);
//#pragma omp parallel for num_threads(线程数)
		for (int32 i = 0; i < num; ++i) {
			vec3 v1, v2, v3;
			vec3 n1, n2, n3;
			if (使用索引) {
				uvec3 index = p索引[i];
				v1 = (vn[index.x].vert);
				v2 = (vn[index.y].vert);
				v3 = (vn[index.z].vert);

				n1 = (vn[index.x].normal);
				n2 = (vn[index.y].normal);
				n3 = (vn[index.z].normal);
			}
			else {
				v1 = (vn[i * 3    ].vert);
				v2 = (vn[i * 3 + 1].vert);
				v3 = (vn[i * 3 + 2].vert);

				n1 = (vn[i * 3].normal);
				n2 = (vn[i * 3 + 1].normal);
				n3 = (vn[i * 3 + 2].normal);
			}
			f_lineMeshTranform(v1, n1, 元素变换属性, mat[0], viewInverseMat, 相机位置);
			f_lineMeshTranform(v2, n2, 元素变换属性, mat[0], viewInverseMat, 相机位置);
			f_lineMeshTranform(v3, n3, 元素变换属性, mat[0], viewInverseMat, 相机位置);
			
			相交情况 = f_graph_IntersectTriangle(v1, v2, v3, s, dir, &相交坐标);
			if (相交情况) {
				float32 距离 = vec_len(vec_sub(相交坐标, 相机位置));
				if (距离 < 拾取信息.相交宽度) {
					拾取信息.相交宽度 = 距离;
					拾取信息.交点 = 相交坐标;
					拾取信息.面索引 = i;
					是否相交 = true;
				}
			}
		}
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		//S_VC* vn = (S_VC*)顶点.point;
		S_VC* vn = f_buf_VC_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vec3 v1, v2, v3;
			if (使用索引) {
				uvec3 index = p索引[i];
				v1 = (vn[index.x].vert);
				v2 = (vn[index.y].vert);
				v3 = (vn[index.z].vert);
			}
			else {
				v1 = (vn[i * 3].vert);
				v2 = (vn[i * 3 + 1].vert);
				v3 = (vn[i * 3 + 2].vert);
			}
			f_lineMeshTranform(v1, {}, 元素变换属性, mat[0], viewInverseMat, 相机位置);
			f_lineMeshTranform(v2, {}, 元素变换属性, mat[0], viewInverseMat, 相机位置);
			f_lineMeshTranform(v3, {}, 元素变换属性, mat[0], viewInverseMat, 相机位置);

			相交情况 = f_graph_IntersectTriangle(v1, v2, v3, s, dir, &相交坐标);
			if (相交情况) {
				float32 距离 = vec_len(vec_sub(相交坐标, 相机位置));
				if (距离 < 拾取信息.相交宽度) {
					拾取信息.相交宽度 = 距离;
					拾取信息.交点 = 相交坐标;
					拾取信息.面索引 = i;
					是否相交 = true;
				}
			}
		}
	}
	else {
		//vec3* p顶点 = (vec3*)顶点.point;
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			uvec3 index = p索引[i];

			vec3 v1 = (v[index.x]);
			vec3 v2 = (v[index.y]);
			vec3 v3 = (v[index.z]);
			f_lineMeshTranform(v1, {}, 元素变换属性, mat[0], viewInverseMat, 相机位置);
			f_lineMeshTranform(v2, {}, 元素变换属性, mat[0], viewInverseMat, 相机位置);
			f_lineMeshTranform(v3, {}, 元素变换属性, mat[0], viewInverseMat, 相机位置);

			相交情况 = f_graph_IntersectTriangle(v1, v2, v3, s, dir, &相交坐标);
			if (相交情况) {
				float32 距离 = vec_len(vec_sub(相交坐标, 相机位置));
				if (距离 < 拾取信息.相交宽度) {
					拾取信息.相交宽度 = 距离;
					拾取信息.交点 = 相交坐标;
					拾取信息.面索引 = i;
					是否相交 = true;
				}
			}
		}
	}

	//min距离 = 最小距离;
	if (是否相交) {
		拾取信息.相交宽度 = length(拾取信息.交点 - 相机位置);
		拾取信息.相交宽度 *= f_mesh_get网格元素绘制属性(mesh).m_DepthScale;
	}

	return 拾取信息;
}




int32 f_surface_线相交(S_Mesh* mesh, const Mat44f& mat, const vec3& s, const vec3& e, float32& 距离) {
	int32 线ID = -1;

	uint32 num = mesh->f_get顶点数量() - 1;
	if (!num) return false;

	//auto 顶点 = mesh->f_map顶点();

	vec3 dir = vec_normalize2(e - s);
	//vec3 dir = (e - s);
	if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_法线) {
		//S_VN* vn = (S_VN*)顶点.point;
		S_VN* vn = f_buf_VN_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vec3 v1 = mat * vn[i].vert;
			vec3 v2 = mat * vn[i + 1].vert;

			float32 两线段距离 = fabs(f_graph_两线段距离(v1, v2, s, dir));
			if (两线段距离 < 距离) {
				距离 = 两线段距离;
				线ID = i;
			}
		}
	}
	else if (*mesh->m_顶点配置Flags == E_顶点组合标志::e_坐标_颜色) {
		//S_VC* vc = (S_VC*)顶点.point;
		S_VC* vc = f_buf_VC_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vec3 v1 = mat * vc[i].vert;
			vec3 v2 = mat * vc[i + 1].vert;
			//v1 = vec_normalize2(v2 - v1);
			float32 两线段距离 = fabs(f_graph_两线段距离(v1, v2, s, dir)); //if(!i)std::cout << "两线段距离:" << 两线段距离 << std::endl;
			if (fabs(两线段距离) < 距离) {
				距离 = 两线段距离;
				线ID = i;
			}
		}
	}
	else {
		//vec3* p顶点 = (vec3*)顶点.point;
		vec3* v = f_buf_Vec3_ptr(*mesh->m_顶点);
		for (uint32 i = 0; i < num; ++i) {
			vec3 v1 = mat * v[i];
			vec3 v2 = mat * v[i+1];

			float32 两线段距离 = fabs(f_graph_两线段距离(v1, v2, s, dir));
			if (两线段距离 < 距离) {
				距离 = 两线段距离;
				线ID = i;
			}
		}
	}

	//mesh->f_unmap顶点();
	return 线ID;
}

static bool f_项排序对比(const uvec2& ia, const uvec2& ib) {
	return (ia.x > ib.x);
}

void f_surface_排列材质槽(S_Mesh* me) {
	S_FaceElement* face = f_buf_面元素_ptr(*me->m_面);

	uint32 num = me->m_面->m_Mem.m_数量;


	std::vector<uvec2> key;
#pragma omp parallel for num_threads(DEF_Min(32, num))
	for (int32 i = 0; i < num; ++i) {
		key[i] = _uVec2(i, face[i].MaterialID);
	}

	std::sort(key.begin(), key.end(), f_项排序对比);

	f_buf_uVec3_ptr(*me->m_索引);

}







vec3 f_SampleSDFGrad(const float* sdf, const uvec3& dim, const ivec3& xyz) {
	int x0 = DEF_Max(xyz.x - 1, 0);
	int x1 = DEF_Min(xyz.x + 1, dim.x - 1);

	int y0 = DEF_Max(xyz.y - 1, 0);
	int y1 = DEF_Min(xyz.y + 1, dim.y - 1);

	int z0 = DEF_Max(xyz.z - 1, 0);
	int z1 = DEF_Min(xyz.z + 1, dim.z - 1);

	float dx = (f_SampleSDF(sdf, dim, x1, xyz.y, xyz.z) - f_SampleSDF(sdf, dim, x0, xyz.y, xyz.z)) * (dim.x * 0.5f);
	float dy = (f_SampleSDF(sdf, dim, xyz.x, y1, xyz.z) - f_SampleSDF(sdf, dim, xyz.x, y0, xyz.z)) * (dim.y * 0.5f);
	float dz = (f_SampleSDF(sdf, dim, xyz.x, xyz.y, z1) - f_SampleSDF(sdf, dim, xyz.x, xyz.y, z0)) * (dim.z * 0.5f);

	return {dx, dy, dz};
}





static Inline S_Mesh* f_mesh_创建体素提取网格(S_Mesh* srcMesh) {
	S_设备环境 ctx; ctx.m_Type = E_绘图API::E_Vulkan; ctx.m_物理设备 = {}; ctx.m_逻辑设备 = {}, E_MS次数::e_MS_1;
	S_Mesh* mesh = f_surface_创建网格对象(srcMesh, ctx, E_网格数据枚举::e_Mesh_CUDA);
	return mesh;
}



void f_load网格(FILE* f, S_Mesh* mesh, uint32 顶点配置标志) {
	uint32 num = 0;

	std::vector<vec3> v;
	num = file_读取序列到文件(f, &v);
	std::vector<vec3> n;
	file_读取序列到文件(f, &n);
	std::vector<uint32> i;
	file_读取序列到文件(f, &i);


	switch (顶点配置标志) {
		case DEF_Vert预设_vn: {
			std::vector<S_VN> data(num);
			for (uint32 i = 0; i < num; ++i) {
				data[i].vert = v[i];
				data[i].normal = n[i];
			}

			mesh->f_填充顶点数据(data);
			f_me_fill索引(mesh, i);
			break;
		}

		case DEF_Vert预设_vnu:
			break;

		default:
			mesh->f_fill顶点(v.data(), v.size());
			mesh->f_fill法线(n);
			f_me_fill索引(mesh, i);
			break;
	}

	
}

void f_save网格(FILE* f, S_Mesh* obj) {
	std::vector<vec3> v;
	obj->f_get顶点((S_结构指针)&v);
	std::vector<vec3> n;
	obj->f_get法线((S_结构指针)&n);
	std::vector<uint32> i;
	obj->f_get索引((S_结构指针)&i);

	
	file_写入序列到文件(f, v);
	file_写入序列到文件(f, n);
	file_写入序列到文件(f, i);
	
}









S_Gpu相交拾取计算::S_Gpu相交拾取计算(S_设备环境& ctx) {
	std::vector<S_着色器创建参数> 参数配置;

	参数配置 = {
		{0, E_着色阶段::e_计算着色, E_板载缓存类型::e_SSBO},
		{1, E_着色阶段::e_计算着色, E_板载缓存类型::e_SSBO},
		{2, E_着色阶段::e_计算着色, E_板载缓存类型::e_SSBO},

		{3, E_着色阶段::e_计算着色, E_板载缓存类型::e_SSBOd},

		{DEF_BINDING_LineProp, E_着色阶段::e_计算着色, E_板载缓存类型::e_SSBO},
	};

	std::vector<S_常量推送创建参数> 常量 = { { E_着色阶段::e_计算着色, 0, sizeof(S_Vert_MeshDrawProp) } };


	m_GpuCtx_坐标_法线_UV = f_df_创建并行计算(ctx, S_引擎配置::m_3D着色器文件根路径 + "射线相交网格.spv", 参数配置, 常量);

	m_属性参数 = f_buf_create板载缓存(m_GpuCtx_坐标_法线_UV->m_Ctx, E_板载缓存类型::e_SSBO, sizeof(S_Pick));
	m_相交数据 = f_buf_create板载缓存(m_GpuCtx_坐标_法线_UV->m_Ctx, E_板载缓存类型::e_SSBOd, sizeof(vec4));
	//S_Gpu实例拾取信息 拾取属性参数 = { mat, s, dir };
	//f_buf_fill板载缓存(拾取属性, &拾取属性参数, sizeof(S_GpuPick));
	//auto* g_索引 = f_buf_create板载缓存(*m_GpuCtx_坐标_法线_UV->m_Ctx, E_板载缓存类型::e_SSBO, sizeof(uvec3));
	m_参数元素[0] = f_buf_create板载缓存(m_GpuCtx_坐标_法线_UV->m_Ctx, E_板载缓存类型::e_SSBO, sizeof(vec3));
	//m_参数元素[1] = g_索引;
	m_参数元素[2] = m_属性参数;
	m_布局位置[2] = 2;

	m_参数元素[3] = m_相交数据;
	m_布局位置[3] = 3;

	m_布局位置[0] = 0;
	m_布局位置[1] = 1;
	
	

	m_布局位置[4] = DEF_BINDING_LineProp;
}

uvec3 S_Gpu相交拾取计算::f_updateGPU参数(S_板载缓存* 顶点, S_GPU内存块& 索引, S_Pick& info, E_顶点组合标志 顶点标志) {
	uvec3 dim = { 1,1,1 };
	dim.x = 索引.m_Mem.m_数量 / 3;

	f_buf_fill板载缓存(m_属性参数, &info, 1);
	f_buf_resize(m_相交数据, dim.x);

	//f_buf_copy板载缓存(m_参数元素[0], 顶点);
	//f_buf_copy(m_参数元素[1], *索引);
	//f_buf_copy板载缓存(m_参数元素[1], 索引);
	//m_参数元素[0] = 顶点;
	//m_参数元素[1] = 索引;
	m_参数元素[1] = 索引.m_Buf;

	m_数据偏移.VertOffset = 0;
	m_数据偏移.IndexOffset = 索引.m_Mem.m_偏移;


	switch (顶点标志) {
		case E_顶点组合标志::e_坐标_法线_UV: {
			std::vector<vec3> vert;
			f_setGPU参数布局(m_GpuCtx_坐标_法线_UV, S_GPU参数布局{ m_参数元素, m_布局位置, nullptr,nullptr,  5, 0 });
			break;
		}
		default:
			break;
	}

	return dim;
}


S_面拾取 f_surface_Gpu射线拾取面(S_Mesh* me, const vec3& s, const vec3& e, const Mat44f 变换矩阵[2], const vec3& 相机位置) {
	S_面拾取 pick_info = { {}, -1, -1 };
	//auto* m = f_ob_fromMesh(ob);
	//assert(m);
	static S_Gpu相交拾取计算* GPU设备 = new S_Gpu相交拾取计算(me->m_Ctx);

	S_Pick info;
	info.matrix = *((mat4*)&变换矩阵[0]);
	info.camera_matrix = *((mat4*)&变换矩阵[1]);
	info.s = { s.x, s.y, s.z, 1 };
	info.dir = { e.x, e.y, e.z, 1 };
	info.indexOffset = me->m_索引->m_Mem.m_偏移 / 3;
	info.vertOffset = 0;

	std::vector<vec3> vert;
	f_surface_get顶点坐标(me, vert);
	f_buf_fill板载缓存(GPU设备->m_参数元素[0], vert);

	GPU设备->m_参数元素[4] = me->m_网格元素变换属性.m_Buf;

	//f_surface_get顶点索引(m, 索引);
	uvec3 dim = GPU设备->f_updateGPU参数(me->m_顶点->m_Buf, *me->m_索引, info, E_顶点组合标志::e_坐标_法线_UV);
	f_GPU_run计算(GPU设备->m_GpuCtx_坐标_法线_UV, dim, me->m_绘制内存属性, sizeof(S_Vert_MeshDrawProp));



	GPU设备->m_参数元素[3]->f_map();
	S_Sphere* pick = (S_Sphere*)(GPU设备->m_参数元素[3]->m_mappedPtr);

	float32 mindir = 90000000;
	for (uint32 i = 0; i < dim.x; ++i) {
		if (pick[i].radius >= 0 && pick[i].radius < mindir) {
			mindir = pick[i].radius;
			pick_info.面索引 = i;
		}
	}

	if (pick_info.面索引 < -1) {
		pick_info.交点 = pick[pick_info.面索引].pos;
		//pick_info.相交距离 = vec_len(pick[pick_info.元素索引].pos - s);
		pick_info.相交宽度 = mindir;

		pick_info.相交宽度 *= f_mesh_get网格元素绘制属性(me).m_DepthScale;
	}

	GPU设备->m_参数元素[3]->f_unmap();

	return pick_info;
}






/*
void f_fromMesh创建体素(S_体素& vo, S_Mesh* srcMesh, vec3 移动, vec3 旋转, vec3 缩放, float 间距, float jitter) {
	if (!srcMesh || 间距 <= 0.0000001) return;

	vo.m_坐标.clear();
	vo.m_法线.clear();

	S_Mesh* mesh = f_mesh_创建体素提取网格(srcMesh);
	{
		Vec3 loc(移动.x, 移动.y, 移动.z );

		//auto 旋转矩阵 = f_构建欧拉角旋转矩阵(旋转);
		auto q = f_graph_欧拉角转四元数(旋转);
		auto 旋转矩阵 = RotationMatrix({ q.x, q.y, q.z, q.w });
		//auto 旋转矩阵 = f_mat_从四元数构建旋转矩阵(旋转.w, { 旋转.x, 旋转.y, 旋转.z });
		//mesh->f_Transform(旋转矩阵);

		Vec3 meshLower, meshUpper;
		mesh->f_getBounds(meshLower, meshUpper);


		//Vec3	edges = (meshUpper - meshLower) * ;
		Vec3	edges	= (meshUpper - meshLower);
		float32	maxEdge	= DEF_Max(DEF_Max(edges.x, edges.y), edges.z);

		// put mesh at the origin and scale to specified size
		// 归一化模型
		//Matrix44 xform = ScaleMatrix(Vec3(缩放.x, 缩放.y, 缩放.z) / maxEdge) * TranslationMatrix(Point3(-meshLower));
		//Matrix44 xform = ScaleMatrix(1.0f / maxEdge) * TranslationMatrix(Point3(-meshLower));
		//mesh->f_Transform(xform);
		// recompute expanded edges
		//edges = meshUpper - meshLower;
		//maxEdge = DEF_Max(DEF_Max(edges.x, edges.y), edges.z);
		// tweak spacing to avoid edge cases for particles laying on the boundary
		// just covers the case where an edge is a whole multiple of the spacing.
		//调整间距，以避免边缘情况下粒子位于边界上
		//仅涵盖边缘是间距的整数倍的情况。
		float 边缘间距 = 间距 * (1.0f - 1e-4f);
		//float 边缘间距 = 间距;
		auto selce = Vec3(缩放.x, 缩放.y, 缩放.z);

		// make sure to have at least one particle in each dimension
		//确保每个方向上至少有一个粒子
		int dx, dy, dz;
		dx = 间距 > edges.x ? 1 : int(edges.x / 边缘间距);
		dy = 间距 > edges.y ? 1 : int(edges.y / 边缘间距);
		dz = 间距 > edges.z ? 1 : int(edges.z / 边缘间距);

		vo.m_维度.x = dx + 4;
		vo.m_维度.y = dy + 4;
		vo.m_维度.z = dz + 4;
		//int maxDim = DEF_Max(DEF_Max(dx, dy), dz);

		// expand border by two voxels to ensure adequate sampling at edges
		//通过两个体素扩展边界以确保在边缘进行足够的采样
		meshLower -= 2.0f * Vec3(间距) + 间距;
		meshUpper += 2.0f * Vec3(间距) + 间距;
		//maxDim += 4;


		uint64 体素数量 = vo.m_维度.x * vo.m_维度.y * vo.m_维度.z;
		std::vector<uint32_t> voxels(体素数量);

		vo.m_Index.resize(体素数量);
		vo.m_Mask.resize(体素数量);

		// we shift the voxelization bounds so that the voxel centers
		// lie symmetrically to the center of the object. this reduces the
		// chance of missing features, and also better aligns the particles
		// with the mesh
		Vec3 meshOffset;
		meshOffset.x = 0.5f * (间距 - (edges.x - (dx - 1) * 间距));
		meshOffset.y = 0.5f * (间距 - (edges.y - (dy - 1) * 间距));
		meshOffset.z = 0.5f * (间距 - (edges.z - (dz - 1) * 间距));
		meshLower -= meshOffset;




		//Voxelize(*mesh, dx, dy, dz, &voxels[0], meshLower - Vec3(spacing*0.05f) , meshLower + Vec3(maxDim*spacing) + Vec3(spacing*0.05f));
		std::vector<Point3>& 顶点 = *((std::vector<Point3>*)mesh->f_get顶点());
		std::vector<Vec3>& 法线 = *((std::vector<Vec3>*)mesh->f_get法线());
		std::vector<uint32>& 索引 = *((std::vector<uint32>*)mesh->f_get索引());
		Voxelize((const Vec3*)顶点.data(),
					顶点.size(),
					(const int32*)索引.data(),
					索引.size(),
					vo.m_维度.x, vo.m_维度.y, vo.m_维度.z,
					&voxels[0],
					meshLower ,
			meshUpper*2);
		//meshLower + Vec3(vo.m_维度.x * 间距, vo.m_维度.y * 间距, vo.m_维度.z * 间距));



		std::vector<float> SDF(体素数量);
		MakeSDF(&voxels[0], vo.m_维度.x, vo.m_维度.y, vo.m_维度.z, &SDF[0]);

		auto* indexs = vo.m_Index.data();
		auto* mask = vo.m_Mask.data();


		for (int z = 0; z < vo.m_维度.z; ++z) {
			int32 层ID = (z * vo.m_维度.x * vo.m_维度.y);

			for (int y = 0; y < vo.m_维度.y; ++y) {
				for (int x = 0; x < vo.m_维度.x; ++x) {
					const int index = 层ID + (y * vo.m_维度.x) + x;

					// if voxel is marked as occupied the add a particle
					if (voxels[index]) {
						indexs[index] = vo.m_坐标.size();

						//Vec3 position = meshLower + 间距 * 2 * Vec3(float(x) + 0.5f, float(y) + 0.5f, float(z) + 0.5f) + RandomUnitVector() * jitter;
						Vec3 position = meshLower + 间距*2.0f * Vec3(float(x), float(y), float(z)) + RandomUnitVector() * jitter;
						//position -= maxEdge*0.5;
						position = 旋转矩阵 * position;
						position = selce * position;


						position += loc - 边缘间距*2;

						vo.m_坐标.push_back(vec3{ position.x, position.y, position.z });

						Vec3 n = SafeNormalize(f_SampleSDFGrad(&SDF[0], vo.m_维度, { int32(x), int32(y), int32(z) }));
						//n *= SDF[index] * maxEdge;
						//vo.m_长度.push_back(SDF[index] * maxEdge);
						vo.m_法线.push_back({ n.x, n.y, n.z, SDF[index] * maxEdge });
						mask[index] = 1;
					}
					else {
						indexs[index] = 0xffffffff;
						mask[index] = 0;
					}
				}
			}
		}
		//mesh->f_Transform(ScaleMatrix(1.0f + skinExpand) * TranslationMatrix(Point3(-0.5f * (meshUpper + meshLower))));
		//mesh->f_Transform(TranslationMatrix(Point3(lower + 0.5f * (meshUpper + meshLower))));

	}

}*/
/*
void f_fromMesh创建体素(S_DomProp& vo, S_Mesh* srcMesh, vec3 移动, vec4 旋转, vec3 缩放, float 间距) {
	S_Mesh* mesh = f_mesh_创建体素提取网格(srcMesh);

	Vec3 loc(移动.x, 移动.y, 移动.z);

	mesh->f_Transform(RotationMatrix(旋转.w, Vec3(旋转.x, 旋转.y, 旋转.z)));
	f_surface_变换顶点(srcMesh, f_ob_get)

	Vec3 meshLower, meshUpper;
	mesh->f_getBounds(meshLower, meshUpper);

	Vec3 edges = meshUpper - meshLower;
	float32 maxEdge = DEF_Max(DEF_Max(edges.x, edges.y), edges.z);

	// 归一化模型
	Matrix44 xform = ScaleMatrix(Vec3(缩放.x, 缩放.y, 缩放.z) / maxEdge) * TranslationMatrix(Point3(-meshLower));
	mesh->f_Transform(xform);
	mesh->f_getBounds(meshLower, meshUpper);

	edges = meshUpper - meshLower;
	maxEdge = DEF_Max(DEF_Max(edges.x, edges.y), edges.z);




	float 边缘间距 = 间距 * (1.0f - 1e-4f);

	//确保每个方向上至少有一个粒子
	int dx, dy, dz;
	dx = 间距 > edges.x ? 1 : int(edges.x / 边缘间距);
	dy = 间距 > edges.y ? 1 : int(edges.y / 边缘间距);
	dz = 间距 > edges.z ? 1 : int(edges.z / 边缘间距);


	//通过两个体素扩展边界以确保在边缘进行足够的采样
	meshLower -= 2.0f * Vec3(间距);
	meshUpper += 2.0f * Vec3(间距);




	Vec3 meshOffset;
	meshOffset.x = 0.5f * (间距 - (edges.x - (dx - 1) * 间距));
	meshOffset.y = 0.5f * (间距 - (edges.y - (dy - 1) * 间距));
	meshOffset.z = 0.5f * (间距 - (edges.z - (dz - 1) * 间距));
	meshLower -= meshOffset;




	//Voxelize(*mesh, dx, dy, dz, &voxels[0], meshLower - Vec3(spacing*0.05f) , meshLower + Vec3(maxDim*spacing) + Vec3(spacing*0.05f));
	std::vector<Point3>& 顶点 = *((std::vector<Point3>*)mesh->f_get顶点());
	std::vector<Vec3>& 法线 = *((std::vector<Vec3>*)mesh->f_get法线());
	std::vector<uint32>& 索引 = *((std::vector<uint32>*)mesh->f_get索引());
	f_Voxelize遮罩(
		(const Vec3*)顶点.data(),
		顶点.size(),
		索引.data(),
		索引.size(),
		vo.m_分辨率.x, vo.m_分辨率.y, vo.m_分辨率.z,
		vo.m_Mask,
		meshLower,
		meshLower + Vec3(vo.m_分辨率.x * 间距, vo.m_分辨率.y * 间距, vo.m_分辨率.z * 间距)
	);

}
*/


//void f_surface_fill面(S_Mesh* me, const std::vector<S_面*>& 面) {
//	f_bm_resize(*me->m_面, 面.size());
//	S_FaceElement* fe = f_buf_面元素_ptr(*me->m_面);
//	for (uint32 i = 0; i < me->m_面->m_Mem.m_数量; ++i) {
//		fe[i].FacesMooth = 面[i]->面平直;
//		//fe[i].MaterialID = 面[i]->材质槽;
//		fe[i].MaterialSlot = 面[i]->材质槽;
//	}
//}



